home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / rspfcmd.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  11KB  |  423 lines

  1. #include "global.h"
  2. #include "config.h"
  3. #include "mbuf.h"
  4. #include "timer.h"
  5. #include "iface.h"
  6. #include "cmdparse.h"
  7. #include "netuser.h"
  8. #include "socket.h"
  9. #include "rspf.h"
  10. #include "ip.h"
  11.  
  12. int Rspfownmode = -1;
  13. static int dointerface __ARGS((int argc,char *argv[],void *p));
  14. static int domessage __ARGS((int argc,char *argv[],void *p));
  15. static int domaxping __ARGS((int argc,char *argv[],void *p));
  16. static int domode __ARGS((int argc,char *argv[],void *p));
  17. static int dorrhtimer __ARGS((int argc,char *argv[],void *p));
  18. static int dotimer __ARGS((int argc,char *argv[],void *p));
  19. static int doroutes __ARGS((int argc,char *argv[],void *p));
  20. static int dostatus __ARGS((int argc,char *argv[],void *p));
  21. static int dosuspect __ARGS((int argc,char *argv[],void *p));
  22. static struct timer rrhtimer, rspftimer;
  23.  
  24. static struct cmds Rspfcmds[] = {
  25.     "interface",    dointerface,    0,      0,      NULLCHAR,
  26.     "message",      domessage,      0,      0,      NULLCHAR,
  27.     "maxping",      domaxping,      0,      0,      NULLCHAR,
  28.     "mode",         domode,         0,      0,      NULLCHAR,
  29.     "rrhtimer",     dorrhtimer,     0,      0,      NULLCHAR,
  30.     "routes",       doroutes,       0,      0,      NULLCHAR,
  31.     "status",       dostatus,       0,      0,      NULLCHAR,
  32.     "suspecttimer", dosuspect,      0,      0,      NULLCHAR,
  33.     "timer",        dotimer,        0,      0,      NULLCHAR,
  34.     NULLCHAR
  35. };
  36.  
  37. int
  38. #ifdef PROTOTYPES
  39. dorspf(int argc,char **argv,void *p)
  40. #else
  41. dorspf(argc,argv,p)
  42. int argc;
  43. char *argv[];
  44. void *p;
  45. #endif
  46. {
  47.     return subcmd(Rspfcmds,argc,argv,p);
  48. }
  49.  
  50. /* The suspect timer controls how often old links expire. When a link has
  51.  * expired, we try to renew its entry by various methods.
  52.  */
  53. static int
  54. dosuspect(argc,argv,p)
  55. int argc;
  56. char *argv[];
  57. void *p;
  58. {
  59.     if(Rspfifaces == NULLRIFACE){
  60.         tprintf("RSPF is not active - define interface first.\n");
  61.         return 0;
  62.     }
  63.     if(argc < 2){
  64.         tprintf("Suspect timer: %lu/%lu seconds\n",
  65.             read_timer(&Susptimer)/1000,
  66.             dur_timer(&Susptimer)/1000);
  67.         return 0;
  68.     }
  69.     Susptimer.func = rspfsuspect; /* what to call on timeout */
  70.     Susptimer.arg = NULL;                   /* dummy value */
  71.     set_timer(&Susptimer,atol(argv[1])*1000L); /* set timer duration */
  72.     start_timer(&Susptimer);                /* and fire it up */
  73.     return 0;
  74. }
  75.  
  76. /* The RRH timer controls the interval between Router-To-Router Hello
  77.  * messages. These messages announce that your station is live and well
  78.  * and that you are willing to exchange RSPF routing updates.
  79.  */
  80. static int
  81. dorrhtimer(argc,argv,p)
  82. int argc;
  83. char *argv[];
  84. void *p;
  85. {
  86.     if(Rspfifaces == NULLRIFACE){
  87.         tprintf("RSPF is not active - define interface first.\n");
  88.         return 0;
  89.     }
  90.     if(argc < 2){
  91.         tprintf("RRH timer: %lu/%lu seconds\n",
  92.             read_timer(&rrhtimer)/1000,
  93.             dur_timer(&rrhtimer)/1000);
  94.         return 0;
  95.     }
  96.     rrhtimer.func = rspfevent; /* what to call on timeout */
  97.     rrhtimer.arg = (void *) &rrhtimer;
  98.     set_timer(&rrhtimer,atol(argv[1])*1000L); /* set timer duration */
  99.     start_timer(&rrhtimer);         /* and fire it up */
  100.     return 0;
  101. }
  102.  
  103. /* This timer controls the interval between the RSPF routing updates. */
  104. static int
  105. dotimer(argc,argv,p)
  106. int argc;
  107. char *argv[];
  108. void *p;
  109. {
  110.     if(Rspfifaces == NULLRIFACE){
  111.         tprintf("RSPF is not active - define interface first.\n");
  112.         return 0;
  113.     }
  114.     if(argc < 2){
  115.         tprintf("RSPF update timer: %lu/%lu seconds\n",
  116.             read_timer(&rspftimer)/1000,
  117.             dur_timer(&rspftimer)/1000);
  118.         return 0;
  119.     }
  120.     rspftimer.func = rspfevent; /* what to call on timeout */
  121.     rspftimer.arg = (void *) &rspftimer;
  122.     set_timer(&rspftimer,atol(argv[1])*1000L); /* set timer duration */
  123.     start_timer(&rspftimer);                /* and fire it up */
  124.     return 0;
  125. }
  126.  
  127. /* Called when either the RRH timer, the Update timer or the Suspect timer
  128.  * expires.
  129.  */
  130. void
  131. rspfevent(t)
  132. void *t;
  133. {
  134.      int cmd;
  135.      struct mbuf *bp;
  136.      struct rspfadj *adj = NULLADJ;
  137.      struct timer *tp;
  138.      tp = (struct timer *) t;
  139.      if(tp == &rrhtimer) {
  140.       cmd = RSPFE_RRH;
  141.       start_timer(tp);
  142.      }
  143.      else if(tp == &rspftimer) {
  144.       cmd = RSPFE_UPDATE;
  145.       start_timer(tp);
  146.      }
  147.      else {
  148.       for(adj = Adjs; adj != NULLADJ; adj = adj->next)
  149.            if(&adj->timer == tp)
  150.             break;
  151.       if(adj == NULLADJ)
  152.            return;
  153.       cmd = RSPFE_CHECK;
  154.      }
  155.      bp = ambufw(1+sizeof(int32));
  156.      *bp->data = cmd;
  157.      memcpy(bp->data + 1,&adj,sizeof(adj));
  158.      bp->cnt = bp->size;
  159.      enqueue(&Rspfinq,bp);
  160. }
  161.  
  162. static int
  163. domessage(argc,argv,p)
  164. int argc;
  165. char *argv[];
  166. void *p;
  167. {
  168.     if(argc > 2) {
  169.         tputs("Usage: rspf message \"<your message>\"\n");
  170.         return 0;
  171.     }
  172.  
  173.     if(argc < 2) {
  174.         if(Rrh_message != NULLCHAR)
  175.             tputs(Rrh_message);
  176.     }
  177.     else {
  178.         if(Rrh_message != NULLCHAR){
  179.             free(Rrh_message);
  180.             Rrh_message = NULLCHAR; /* reset the pointer */
  181.         }
  182.         if(!strlen(argv[1]))
  183.             return 0;               /* clearing the buffer */
  184.         Rrh_message = mallocw(strlen(argv[1])+5);/* allow for EOL */
  185.         strcpy(Rrh_message, argv[1]);
  186.         strcat(Rrh_message, INET_EOL);  /* add the EOL char */
  187.     }
  188.     return 0;
  189. }
  190.  
  191. static int
  192. domaxping(argc,argv,p)
  193. int argc;
  194. char *argv[];
  195. void *p;
  196. {
  197.      return setshort(&Rspfpingmax,"Max failed pings before deleting adjacency",
  198.              argc,argv);
  199. }
  200.  
  201. static int
  202. domode(argc,argv,p)
  203. int argc;
  204. char *argv[];
  205. void *p;
  206. {
  207.     if(argc < 2) {
  208.     tputs("RSPF preferred mode is ");
  209.     if(Rspfownmode == -1)
  210.         tputs("not set.\n");
  211.     else
  212.         tprintf("%s.\n",(Rspfownmode & CONNECT_MODE) ? "VC mode" :
  213.            "Datagram mode");
  214.     return 0;
  215.     }
  216.     switch(*argv[1]){
  217.     case 'v':
  218.     case 'c':
  219.     case 'V':
  220.     case 'C':
  221.     Rspfownmode = CONNECT_MODE;
  222.     break;
  223.     case 'd':
  224.     case 'D':
  225.     Rspfownmode = DATAGRAM_MODE;
  226.     break;
  227.     case 'n':
  228.     case 'N':
  229.     Rspfownmode = -1;
  230.     break;
  231.     default:
  232.     tputs("Usage: rspf mode [vc | datagram | none]\n");
  233.     return 1;
  234.     }
  235.     return 0;
  236. }
  237.  
  238. #ifdef AUTOROUTE
  239. int RspfActive = 0;
  240. extern int Ax25_autoroute;
  241. #endif
  242.  
  243. static int
  244. dointerface(argc,argv,p)
  245. int argc;
  246. char *argv[];
  247. void *p;
  248. {
  249.     struct rspfiface *riface;
  250.     struct iface *iface;
  251.     struct mbuf *bp;
  252.     int h,q;
  253.     if(argc < 2){
  254.     tputs("Iface    Quality    Horizon\n");
  255.     for(riface = Rspfifaces; riface != NULLRIFACE; riface = riface->next)
  256.         tprintf("%-9s%-11d%-11d\n",riface->iface->name,riface->quality,
  257.            riface->horizon);
  258.     return 0;
  259.     }
  260.     if(argc != 4){
  261.     tputs("Usage: rspf interface <name> <quality> <horizon>\n");
  262.     return 1;
  263.     }
  264.     if((iface = if_lookup(argv[1])) == NULLIF){
  265.     tputs("No such interface.\n");
  266.     return 1;
  267.     }
  268.     if(iface->broadcast == 0){
  269.     tprintf("Broadcast address for interface %s not set\n",argv[1]);
  270.     return 1;
  271.     }
  272.     q = atoi(argv[2]);
  273.     if(q < 1 || q > 127){
  274.     tputs("Quality must be between 1 and 127\n");
  275.     return 1;
  276.     }
  277.     h = atoi(argv[3]);
  278.     if(h < 1 || h > 255){
  279.     tputs("Horizon must be between 1 and 255\n");
  280.     return 1;
  281.     }
  282.     riface = (struct rspfiface *)callocw(1,sizeof(struct rspfiface));
  283.     riface->iface = iface;
  284.     riface->quality = q;
  285.     riface->horizon = h;
  286.     riface->next = Rspfifaces;
  287.     if(Rspfifaces == NULLRIFACE) {
  288. #ifdef AUTOROUTE
  289.     RspfActive = 1;        /* Make sure ARP autorouting is off ! - WG7J */
  290.     Ax25_autoroute = 0;
  291. #endif
  292.     newproc("RSPF",2048,rspfmain,0,NULL,NULL,0);
  293.     }
  294.     Rspfifaces = riface;
  295.     bp = ambufw(1+sizeof(int32));
  296.     *bp->data = RSPFE_RRH;              /* Send an RRH immediately */
  297.     memcpy(bp->data + 1,&riface,sizeof(riface));
  298.     bp->cnt = bp->size;
  299.     enqueue(&Rspfinq,bp);
  300.     return 0;
  301. }
  302.  
  303. /* Display accumulated routing updates */
  304. static int
  305. doroutes(argc,argv,p)
  306. int argc;
  307. char *argv[];
  308. void *p;
  309. {
  310.     struct mbuf *bp;
  311.     struct rspfrouter *rr;
  312.     if(Rspfifaces == NULLRIFACE){
  313.     tprintf("RSPF is not active - define interface first.\n");
  314.     return 0;
  315.     }
  316.     bp = makeownupdate(INADDR_ANY,0);
  317.     if(bp == NULLBUF && Rspfrouters == NULLRROUTER) {
  318.      tputs("No routing information is available.\n");
  319.      return 0;
  320.     }
  321.     if(bp != NULLBUF) {
  322.     tputs("      Local routing update:\n");
  323. #ifdef MONITOR
  324.     rspfnodedump(NULLFILE,&bp,0,0);
  325. #else
  326.     rspfnodedump(NULLFILE,&bp,0);
  327. #endif
  328.     tputc('\n');
  329.     }
  330.     for(rr = Rspfrouters; rr != NULLRROUTER; rr = rr->next) {
  331.     tprintf("      Time since receipt: %s",tformat(secclock() - rr->time));
  332.     if(rr->subseq != 0)
  333.          tprintf("  Last subseq: %u",uchar(rr->subseq));
  334.     if(rr->sent)
  335.          tputs("  Propagated");
  336.     tputc('\n');
  337.     if(rr->data != NULLBUF) {
  338.          dup_p(&bp,rr->data,0,len_p(rr->data));
  339. #ifdef MONITOR
  340.          rspfnodedump(NULLFILE,&bp,0,0);
  341. #else
  342.          rspfnodedump(NULLFILE,&bp,0);
  343. #endif
  344.          tputc('\n');
  345.     }
  346.     }
  347.     return 0;
  348. }
  349.  
  350. static int
  351. dostatus(argc,argv,p)
  352. int argc;
  353. char *argv[];
  354. void *p;
  355. {
  356.     struct rspfreasm *re;
  357.     struct rspfadj *adj;
  358.     struct mbuf *bp;
  359.     union rspf rspf;
  360.     if(Rspfifaces == NULLRIFACE){
  361.         tprintf("RSPF is not active - define interface first.\n");
  362.         return 0;
  363.     }
  364.     tprintf("Bad checksum %u  Bad version %u  Not RSPF interface %u\n",
  365.         Rspf_stat.badcsum,Rspf_stat.badvers,Rspf_stat.norspfiface);
  366.     tprintf("RRH in %u  RRH out %u  Update in %u  Update out %u\n",
  367.         Rspf_stat.rrhin,Rspf_stat.rrhout,Rspf_stat.updatein,
  368.         Rspf_stat.updateout);
  369.     tprintf("Non-adjacency update %u  Old node report %u  Polls sent %u\n",
  370.         Rspf_stat.noadjupdate,Rspf_stat.oldreport,Rspf_stat.outpolls);
  371.     if(Adjs == NULLADJ)
  372.         return 0;
  373.     tputs("Addr            Cost    Seq    Heard    Timer     TOS    State\n");
  374.     for(adj = Adjs; adj != NULLADJ; adj = adj->next) {
  375.         tprintf("%-15s %4u  %5u   %6lu ", inet_ntoa(adj->addr),
  376.             uchar(adj->cost),adj->seq,adj->heard);
  377.         if(run_timer(&adj->timer))
  378.              tprintf("%5lu/%-5lu",
  379.             read_timer(&adj->timer)/1000L ,dur_timer(&adj->timer)/1000L);
  380.         else
  381.              tprintf("%11s","");
  382.         tprintf("  %3u    ", uchar(adj->tos));
  383.         switch(adj->state) {
  384.         case RSPF_TENTATIVE:
  385.             tputs("Tentative");
  386.             break;
  387.         case RSPF_OK:
  388.             tputs("OK");
  389.             break;
  390.         case RSPF_SUSPECT:
  391.             tputs("Suspect");
  392.             break;
  393.         case RSPF_BAD:
  394.             tputs("Bad");
  395.             break;
  396.         default:
  397.             tputs("Unknown");
  398.             break;
  399.         }
  400.         tputc('\n');
  401.     }
  402.     if(run_timer(&Rspfreasmt)) {
  403.          tprintf("Reassembly timer running: %lu/%lu seconds\n",
  404.              read_timer(&Rspfreasmt)/1000L, dur_timer(&Rspfreasmt)/1000L);
  405.     }
  406.     if(Rspfreasmq != NULLRREASM)
  407.          tputs("Reassembly fragments:\n");
  408.     for(re = Rspfreasmq; re != NULLRREASM; re = re->next) {
  409.          tprintf("src %s time since last frag %s",inet_ntoa(re->addr),
  410.              tformat((secclock() - re->time)));
  411.          if(dup_p(&bp,re->data,0,RSPFPKTLEN) == RSPFPKTLEN &&
  412.         ntohrspf(&rspf,&bp) != -1)
  413.           tprintf(" frag count %u/%u\n",len_q(re->data),
  414.               rspf.pkthdr.fragtot);
  415.          else {
  416.           tputc('\n');
  417.           free_p(bp);
  418.           continue;
  419.          }
  420.     }
  421.     return 0;
  422. }
  423.